/*
Pyxis 2.0
Copyright 2010-2011 Thomas W. Holtquist

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

using System.Collections;
using System.IO;
using System.Xml;

using System.Ext.Xml;
using Microsoft.SPOT;

namespace Skewworks.Pyxis.Kernel
{

    public class XMLReaderEX
    {

        #region Variables

        private ArrayList _nodes = new ArrayList();

        #endregion

        #region Constructor

        public XMLReaderEX(string Filename)
        {
            // Read the file
            FileStream iFile = new FileStream(Filename, FileMode.Open);
            byte[] data = new byte[iFile.Length];
            iFile.Read(data, 0, data.Length);
            iFile.Close();

            // Create the Memory Stream
            MemoryStream ms = new MemoryStream(data);

            // Read XML Structure
            ReadStructure(ms);
        }

        public XMLReaderEX(MemoryStream MS)
        {
            // Read XML Structure
            ReadStructure(MS);
        }

        public XMLReaderEX(FileStream FS)
        {
            byte[] data = new byte[FS.Length];
            FS.Read(data, 0, data.Length);
            FS.Close();

            // Create the Memory Stream
            MemoryStream ms = new MemoryStream(data);

            // Read XML Structure
            ReadStructure(ms);
        }

        public XMLReaderEX(byte[] Data)
        {
            // Create the Memory Stream
            MemoryStream ms = new MemoryStream(Data);

            // Read XML Structure
            ReadStructure(ms);
        }

        #endregion

        #region Properties

        public ArrayList Nodes
        {
            get { return _nodes; }
        }

        #endregion

        #region Public Methods

        public XMLNodeEX NodeByName(string Name)
        {
            XMLNodeEX node = null;
            for (int i = 0; i < _nodes.Count; i++)
            {
                node = (XMLNodeEX)_nodes[i];
                if (node.Name == Name) return node;
            }
            return null;
        }

        #endregion

        #region Private Methods

        private void ReadStructure(MemoryStream ms)
        {
            // Create Base Node
            XMLNodeEX node = null;
            XMLNodeEX subn = null;
            XMLNodeEX curn = null;

            // Create Reader Settings
            XmlReaderSettings ss = new XmlReaderSettings();
            ss.IgnoreWhitespace = true;
            ss.IgnoreComments = false;

            // Create Reader
            XmlReader xr = XmlReader.Create(ms, ss);

            // Loop through nodes to create structure
            while (!xr.EOF)
            {
                xr.Read();
                switch (xr.NodeType)
                {
                    case XmlNodeType.Element:
                        if (node == null)
                        {
                            node = new XMLNodeEX(xr.Name);
                            curn = node;
                            _nodes.Add(node);
                        }
                        else
                        {
                            subn = new XMLNodeEX(xr.Name, curn);
                            curn.Nodes.Add(subn);
                            curn = subn;
                        }
                        break;
                    case XmlNodeType.Text:
                        curn.value = xr.Value;
                        break;
                    case XmlNodeType.XmlDeclaration:
                    case XmlNodeType.Comment:
                    case XmlNodeType.Whitespace:
                    case XmlNodeType.None:
                        // We do not care
                        break;
                    case XmlNodeType.EndElement:
                        curn = curn.Parent;
                        if (curn == null) node = null;
                        break;
                    default:
                        Debug.Print(xr.NodeType.ToString());
                        break;
                }
            }

        }

        #endregion

    }

    public class XMLNodeEX
    {

        #region Variables

        private string _name;
        private string _value;
        private ArrayList _nodes = new ArrayList();
        private XMLNodeEX _parent = null;

        #endregion

        #region Constructor

        internal XMLNodeEX(string Name)
        {
            _name = Name;
        }

        internal XMLNodeEX(string Name, XMLNodeEX Parent)
        {
            _name = Name;
            _parent = Parent;
        }

        #endregion

        #region Properties

        public string Name
        {
            get { return _name; }
            internal set { _name = value; }
        }

        public ArrayList Nodes
        {
            get { return _nodes; }
        }

        public XMLNodeEX Parent
        {
            get { return _parent; }
        }

        public string value
        {
            get { return _value; }
            internal set { _value = value; }
        }

        public bool valueToBool
        {
            get
            {
                if (_value.ToLower() == "false" || _value == "0") return false;
                return true;
            }
        }

        #endregion

        #region Public Methods

        public XMLNodeEX NodeByName(string Name)
        {
            XMLNodeEX node = null;
            for (int i = 0; i < _nodes.Count; i++)
            {
                node = (XMLNodeEX)_nodes[i];
                if (node.Name == Name) return node;
            }
            return null;
        }

        #endregion

    }

}
